/* Copyright (C) 2011
  This file is part of the shamir OTP library
  
  Shamir-otp is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
  
  Shamir-otp is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  02110-1301, USA */
#include <stdio.h>
#include "shamir_OTP.h"

int main(int argc, char *argv[])
{
   if(argc < 3)
   {
      fprintf(stderr, "NAME\n");
      fprintf(stderr, "      shamir-test-otp - create a profile for use with shamirOTP\n\n");
      fprintf(stderr, "SYNOPSIS\n");
      fprintf(stderr, "      shamir-test-otp SERVER_PROFILE OTP\n\n");
      fprintf(stderr, "DESCRIPTION\n");
      fprintf(stderr, "      Test a password OTP for profile SERVER_PROFILE for validity.\n\n");
      return 0;
   }
   else 
   {
      mpz_t otp;          /* The command-line provided OTP */
      profile_t profile;  /* The command-line provied profile */

      if(mpz_init_set_str(otp, argv[2], 16) != 0)
      {
         fprintf(stderr, "Invalid OTP syntax!\n");
         return -1;
      }
      load_profile(&profile, argv[1]);

      if(check_otp(profile, otp) == 0)
      {
         /* Provided to authetnciator and generated by generator */
         verification_t for_generator_verification;
         /* Given to the generator provided by authenticator */
         verification_t from_generator_verification;
         /* Provided by generator */
         mpz_t from_generator_material; 
         /* Update information */
         update_t update;

         printf("The OTP is valid.\n");
         fflush(stdout);

         /* Get our share and their share */
         generate_update_material(profile, &update);

         /* Output information for user */
         mpz_init(from_generator_material);
         printf("Please provide the Update number to your OTP generator: ");
         gmp_printf("%Zx\n", update.for_generator);

         /* Request information from user */
         printf("Please enter the Update number provided by your OTP generator:\n");
         gmp_scanf("%Zx", from_generator_material);
      
         /* Output verification information */
         generate_verification_material(profile, &for_generator_verification, update);
         printf("Please provide the E0 number to your OTP generator: ");
         gmp_printf("%Zx\n", for_generator_verification.E0);
         printf("Please provide the E1 number to your OTP generator: ");
         gmp_printf("%Zx\n", for_generator_verification.E1);
         printf("Please provide the r number to your OTP generator: ");
         gmp_printf("%Zx\n", for_generator_verification.rOfI);
         
         /* Accept verification information */
         mpz_init(from_generator_verification.E0);
         mpz_init(from_generator_verification.E1);
         mpz_init(from_generator_verification.rOfI);
         printf("Please enter the E0 number provided by your generator:\n");
         gmp_scanf("%Zx", from_generator_verification.E0);
         printf("Please enter the E1 number provided by your generator:\n");
         gmp_scanf("%Zx", from_generator_verification.E1);
         printf("Please enter the r number provided by your generator:\n");
         gmp_scanf("%Zx", from_generator_verification.rOfI);

         /* Finalize update */
         if(verify_update_material(profile, 
                                   from_generator_verification,
                                   from_generator_material) == 0)
         {
            update_profile(&profile, update.for_authenticator, from_generator_material);
            /* Save profile */
            printf("Saving updated profile...");
            fflush(stdout);
            save_profile(profile, argv[1]);
            printf("done\n");
         }
         else
         {
            printf("Error: The update material appears to be malicious!\n");
            printf("Aborting. Please try again.\n");
            return 0;
         }
      }
      else
      {
         printf("The OTP is invalid.\n");
      }
   }
   return 0;
}
